<script setup>
import { ref, shallowRef, onMounted, onUnmounted } from 'vue';
import * as THREE from 'three';
import { FBXLoader } from 'three/examples/jsm/loaders/FBXLoader';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';

// 使用shallowRef避免Three.js对象被深度响应式代理
const scene = shallowRef(null);
const camera = shallowRef(null);
const renderer = shallowRef(null);
const controls = shallowRef(null);
const model = shallowRef(null);
const canvas = ref(null);

// 使用ref用于响应式数据
const isLoading = ref(false);
const modelPosition = ref({ x: 0, y: 0, z: 0 });
const modelScale = ref(1);

// 初始化Three.js场景
const initScene = () => {
    // 创建场景
    scene.value = new THREE.Scene();
    scene.value.background = new THREE.Color(0x1a1a2e);
    scene.value.fog = new THREE.Fog(0x1a1a2e, 10, 20);

    // 创建相机
    camera.value = new THREE.PerspectiveCamera(
        75,
        window.innerWidth / window.innerHeight,
        0.1,
        1000
    );
    camera.value.position.set(0, 2, 5);

    // 创建渲染器
    renderer.value = new THREE.WebGLRenderer({
        antialias: true,
        canvas: canvas.value
    });
    renderer.value.setSize(window.innerWidth, window.innerHeight);
    renderer.value.shadowMap.enabled = true;
    renderer.value.shadowMap.type = THREE.PCFSoftShadowMap;

    // 添加轨道控制器
    controls.value = new THREE.OrbitControls(camera.value, renderer.value.domElement);
    controls.value.enableDamping = true;
    controls.value.dampingFactor = 0.05;

    // 添加灯光
    const ambientLight = new THREE.AmbientLight(0x404040, 0.8);
    scene.value.add(ambientLight);

    const directionalLight = new THREE.DirectionalLight(0xffffff, 1);
    directionalLight.position.set(5, 10, 7.5);
    directionalLight.castShadow = true;
    directionalLight.shadow.mapSize.width = 1024;
    directionalLight.shadow.mapSize.height = 1024;
    scene.value.add(directionalLight);

    // 添加网格地面
    const gridHelper = new THREE.GridHelper(10, 10, 0x00ff00, 0x444444);
    scene.value.add(gridHelper);

    const floorGeometry = new THREE.PlaneGeometry(10, 10);
    const floorMaterial = new THREE.MeshStandardMaterial({
        color: 0x222222,
        metalness: 0,
        roughness: 0.8
    });
    const floor = new THREE.Mesh(floorGeometry, floorMaterial);
    floor.rotation.x = -Math.PI / 2;
    floor.receiveShadow = true;
    scene.value.add(floor);

    // 添加坐标轴辅助
    const axesHelper = new THREE.AxesHelper(3);
    scene.value.add(axesHelper);
};

// 加载模型
const loadModel = (type = 'cube') => {
    isLoading.value = true;

    // 使用setTimeout模拟加载过程
    setTimeout(() => {
        // 移除旧模型（如果存在）
        if (model.value) {
            scene.value.remove(model.value);
        }

        let geometry;

        if (type === 'cube') {
            geometry = new THREE.BoxGeometry(1, 1, 1);
        } else if (type === 'sphere') {
            geometry = new THREE.SphereGeometry(0.7, 32, 32);
        } else if (type === 'torus') {
            geometry = new THREE.TorusGeometry(0.5, 0.2, 16, 100);
        } else if (type === 'cone') {
            geometry = new THREE.ConeGeometry(0.7, 1.5, 32);
        }

        const material = new THREE.MeshStandardMaterial({
            color: 0x4cc9f0,
            metalness: 0.5,
            roughness: 0.2
        });

        // 创建新模型
        model.value = new THREE.Mesh(geometry, material);
        model.value.castShadow = true;
        model.value.position.set(0, 0.5, 0);
        scene.value.add(model.value);

        // 更新位置显示
        updatePositionDisplay();

        isLoading.value = false;
    }, 1000);
};

// 更新模型位置显示
const updatePositionDisplay = () => {
    if (model.value) {
        modelPosition.value = {
            x: model.value.position.x.toFixed(2),
            y: model.value.position.y.toFixed(2),
            z: model.value.position.z.toFixed(2)
        };
    }
};

// 动画循环
const animate = () => {
    requestAnimationFrame(animate);
    if (controls.value) {
        controls.value.update();
    }
    if (renderer.value && scene.value && camera.value) {
        renderer.value.render(scene.value, camera.value);
    }
};

// 处理窗口大小变化
const onWindowResize = () => {
    if (camera.value && renderer.value) {
        camera.value.aspect = window.innerWidth / window.innerHeight;
        camera.value.updateProjectionMatrix();
        renderer.value.setSize(window.innerWidth, window.innerHeight);
    }
};

// 处理鼠标移动模型
const setupModelMovement = () => {
    const canvas = renderer.value.domElement;
    let isDragging = false;
    let previousMousePosition = {
        x: 0,
        y: 0
    };

    canvas.addEventListener('mousedown', (e) => {
        isDragging = true;
        previousMousePosition = {
            x: e.clientX,
            y: e.clientY
        };
    });

    canvas.addEventListener('mouseup', () => {
        isDragging = false;
    });

    canvas.addEventListener('mousemove', (e) => {
        if (!isDragging || !model.value) return;

        const deltaMove = {
            x: e.clientX - previousMousePosition.x,
            y: e.clientY - previousMousePosition.y
        };

        // 根据鼠标移动调整模型位置（仅在X和Y轴上移动）
        model.value.position.x += deltaMove.x * 0.01;
        model.value.position.y -= deltaMove.y * 0.01;

        // 确保Z轴始终为0
        model.value.position.z = 0;

        // 更新位置显示
        updatePositionDisplay();

        previousMousePosition = {
            x: e.clientX,
            y: e.clientY
        };
    });
};

// 调整模型大小
const updateModelScale = () => {
    if (model.value) {
        model.value.scale.set(modelScale.value, modelScale.value, modelScale.value);
    }
};

// 重置模型位置
const resetModelPosition = () => {
    if (model.value) {
        model.value.position.set(0, 0.5, 0);
        updatePositionDisplay();
    }
};

onMounted(() => {
    initScene();
    animate();
    window.addEventListener('resize', onWindowResize, false);

    // 初始加载一个模型
    loadModel();

    // 设置模型移动事件（需要在渲染器dom元素创建后调用）
    setTimeout(setupModelMovement, 100);
});

onUnmounted(() => {
    window.removeEventListener('resize', onWindowResize);
    if (renderer.value) {
        renderer.value.dispose();
    }
});


onMounted(() => {
    // 挂载后初始化（同上）
});

onUnmounted(() => {
    // 清理代码（同上）
});
</script>

<template>
    <div class="container">
        <div class="canvas-container">
            <canvas ref="canvas" class="three-canvas"></canvas>
            <div v-if="isLoading" class="loading-overlay">
                <div class="spinner"></div>
                <div class="loading-text">加载模型中...</div>
            </div>
        </div>

        <div class="controls-panel">
            <div class="control-group">
                <h3>模型控制</h3>
                <div class="model-selector">
                    <button class="btn model-btn" @click="loadModel('cube')">立方体</button>
                    <button class="btn model-btn" @click="loadModel('sphere')">球体</button>
                    <button class="btn model-btn" @click="loadModel('torus')">圆环</button>
                    <button class="btn model-btn" @click="loadModel('cone')">圆锥</button>
                </div>

                <button class="btn" @click="resetModelPosition">重置位置</button>

                <div style="margin-top: 15px;">
                    <label>模型大小: </label>
                    <input type="range" min="0.5" max="2" step="0.1" v-model="modelScale" @input="updateModelScale">
                    <span>{{ modelScale }}x</span>
                </div>

                <div class="position-display">
                    <div>X: <span class="position-value">{{ modelPosition.x }}</span></div>
                    <div>Y: <span class="position-value">{{ modelPosition.y }}</span></div>
                    <div>Z: <span class="position-value">{{ modelPosition.z }}</span> <span
                            class="highlight">(固定)</span></div>
                </div>
            </div>

            <div class="control-group">
                <h3>相机控制</h3>
                <p>左键拖动: 旋转视角</p>
                <p>右键拖动: 平移视角</p>
                <p>滚轮: 缩放</p>
            </div>

            <div class="instructions">
                <h3>使用说明</h3>
                <p>1. 从上方选择要加载的模型类型</p>
                <p>2. 在画布上<span class="highlight">点击并拖动鼠标</span>来移动模型</p>
                <p>3. 使用<span class="highlight">滑块</span>调整模型大小</p>
                <p>4. 使用鼠标<span class="highlight">右键拖动</span>来移动相机视角</p>
                <p>5. 使用<span class="highlight">滚轮</span>缩放场景</p>
                <p>6. 点击"<span class="highlight">重置位置</span>"将模型放回中心</p>
            </div>
        </div>
    </div>
</template>

<style scoped>
/* 样式代码（同上） */
</style>